/*
 * Fecha:  01-03-2012
 * @author Paco FELC
 *
 * Funciones Sociales
 *
 * Se accede a través de social.jsp
 * Siempre se comprueba la sesión incluso para operaciones de consulta.
 *
 * Los parámetros definen las operaciones a realizar:
 *      parametro op - operación
 *          valor a - append / insert
 *          valor d - delete / remove
 *          valor l - list / select
 *      parametro t - tipo
 *          valor f - friend / buddy list
 *          valor b - black list / ignored people
 *      parametro id - identificador del elemento de la lista a tratar (usuario_id),
 *          obligatorio para operaciones a/d
 *
 * retorno error=xx;
 *      xx=  0 - Operación correcta
 *      xx= -1 -
 *      xx= -2 - Usuario no existe
 *      xx= -3 -
 *
 * Retorno de la operación list:
 *
     -3, "Elemento no existe"
     -4, "Operación Incorrecta"
     -5, "Operación Incorrecta"
     -6, "Tipo Incorrecto"
     -7, "Sesión Incorrecta"
     -8, "Tipo Incorrecto"
     -9, "Sesión Incorrecta"
    -10, "Elemento existe"
    -11, "Máximo Amigos"
    -12, "Máximo Ignorados"
    -13, "Usuario en la otra lista"
 *
 */

package com.bitoon.basketdudes.ws;
import org.apache.log4j.*;
import com.bitoon.basketdudes.jpa.*;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @author PacoFELC
 *
 *
 */
public class Social {
    Logger                  log         = Logger.getLogger(Social.class);
    EntityManagerFactory    emf         = null;
    String                  m_cadena    = "";

    private static final int MAX_LISTA = 100;

    public Social( ) {
        try {
            // JPA Units
log.debug("[EMF INI] " );
            emf = PersistenceManager.getInstance().getEntityManagerFactory("jpa_basket");
log.debug("[EMF FIN] " +emf );
        } catch (Exception e) {
            log.error("[ERROR][constructor]: No se puedo conectar a la base de datos: " , e);
        }
    }

    public String getCadena() {
        return m_cadena;
    }

    /*
    public void setEntityManager ( EntityManager p_basket ) {
        try {
            // JPA Units
            em   = p_basket;
        } catch (Exception e) {
            log.error("[ERROR][constructor]: No se puedo conectar a la base de datos: " , e);
        }
    }
     * 
     */

    /*
    public EntityManager getEntityManager (  ) {
        try {
            if ( em == null) {
                emf      = PersistenceManager.getInstance().getEntityManagerFactory("jpa_basket");
                em  = emf.createEntityManager(); // check 08.08.2012
            }

        } catch (Exception e) {
            log.error("[ERROR][constructor]: No se puedo conectar a la base de datos: " , e);
        }
        return em;
    }
     * 
     */

    public int getLista ( EntityManager em, boolean p_amigos, int propietario ) {

        if ( p_amigos == true )
        {
            Query q = em.createNamedQuery("Amigo.findByPropietario");
            q.setParameter("propietario" , propietario );
            
            List<Amigo>lista = q.getResultList();
            if ( lista!= null && !lista.isEmpty() ) {
                for ( int i=0;i<lista.size();i++) {
                    m_cadena += String.valueOf(lista.get(i).getAmigoPK().getUsuarioId())+',';
                }
            }
        }
        else
        {
            Query q = em.createNamedQuery("Ignorado.findByPropietario");
            q.setParameter("propietario" , propietario );

            List<Ignorado>lista = q.getResultList();
            if ( lista!= null && !lista.isEmpty() ) {
                for ( int i=0;i<lista.size();i++) {
                    m_cadena += String.valueOf(lista.get(i).getIgnoradoPK().getUsuarioId())+',';
                }
            }
        }
        return 0;
    }

    public int appendLista ( EntityManager p_em, boolean p_amigos, int p_propietario, 
                             int p_usuario_id ) throws ExcepcionGeneral  {
        try {
            if ( p_amigos == true )
            {
                Amigo elemento = buscarElementoAmigo( p_em, p_propietario, p_usuario_id );
                if ( elemento == null) {

                    if ( totalListaAmigos(p_em, p_propietario).intValue() >=MAX_LISTA ) {
                        throw new ExcepcionGeneral( -11, "Máximo Amigos alcanzado" );
                    }
                    Ignorado en_la_otra_lista = buscarElementoIgnorado( p_em, p_propietario, p_usuario_id );
                    if ( en_la_otra_lista != null) {
                        throw new ExcepcionGeneral( -13, "Usuario en la otra lista" + p_usuario_id  );
                    }

                    AmigoPK pk_amigo    = new AmigoPK();
                    Amigo   amigo       = new Amigo();

                    pk_amigo.setPropietario(p_propietario);
                    pk_amigo.setUsuarioId(p_usuario_id);

                    amigo.setAmigoPK(pk_amigo);
                    p_em.persist(amigo);
                } else {
                    throw new ExcepcionGeneral( -10, "Elemento existe" + p_usuario_id  );
                }
            }
            else
            {
                Ignorado elemento = buscarElementoIgnorado( p_em, p_propietario, p_usuario_id );
                if ( elemento == null) {

                    if ( totalListaIgnorados(p_em, p_propietario).intValue() >=MAX_LISTA ) {
                        throw new ExcepcionGeneral( -12, "Máximo Ignorados alcanzado" );
                    }
                    Amigo en_la_otra_lista = buscarElementoAmigo( p_em, p_propietario, p_usuario_id );
                    if ( en_la_otra_lista != null) {
                        throw new ExcepcionGeneral( -13, "Usuario en la otra lista" + p_usuario_id  );
                    }

                    IgnoradoPK pk_ignorado  = new IgnoradoPK();
                    Ignorado ignorado       = new Ignorado();

                    pk_ignorado.setPropietario(p_propietario);
                    pk_ignorado.setUsuarioId(p_usuario_id);

                    ignorado.setIgnoradoPK(pk_ignorado);
                    p_em.persist(ignorado);
                } else {
                    throw new ExcepcionGeneral( -10, "Elemento existe" + p_usuario_id  );
                }
            }
        } catch (Exception e) {
            log.error("[ERROR][wsSocial]: " , e);
        }
        return 0;
    }

    public Amigo buscarElementoAmigo ( EntityManager p_em, int p_propietario,
                                    int p_usuario_id ) throws ExcepcionGeneral {
        Query q = p_em.createNamedQuery("Amigo.findElemento");
        q.setParameter("propietario" , p_propietario );
        q.setParameter("usuario_id"  , p_usuario_id );

        List<Amigo>lista = q.getResultList();
        if ( lista.isEmpty() )
            return null;
        else
            return lista.get(0);
    }

    public Ignorado buscarElementoIgnorado ( EntityManager p_em, int p_propietario,
                                             int p_usuario_id ) throws ExcepcionGeneral {
        Query q = p_em.createNamedQuery("Ignorado.findElemento");
        q.setParameter("propietario" , p_propietario );
        q.setParameter("usuario_id"  , p_usuario_id );

        List<Ignorado>lista = q.getResultList();
        if ( lista.isEmpty() )
            return null;
        else
            return lista.get(0);
    }

    public Number totalListaIgnorados ( EntityManager p_em, int p_propietario ) throws ExcepcionGeneral {
        Query q = p_em.createNamedQuery("Ignorado.countAll");
        q.setParameter("propietario" , p_propietario );

        return (Number) q.getSingleResult();
    }
    
    public Number totalListaAmigos ( EntityManager p_em, int p_propietario ) throws ExcepcionGeneral {
        Query q = p_em.createNamedQuery("Amigo.countAll");
        q.setParameter("propietario" , p_propietario );

        return (Number) q.getSingleResult();
    }


    public int removeLista ( EntityManager p_em, boolean p_amigos, int p_propietario,
                             int p_usuario_id ) throws ExcepcionGeneral {
        if ( p_amigos == true )
        {
            Amigo elemento = buscarElementoAmigo( p_em, p_propietario, p_usuario_id );
            if ( elemento == null) {
                throw new ExcepcionGeneral( -3, "Elemento no existe" + p_usuario_id  );
            }
            p_em.remove(elemento);
        }
        else
        {
            Ignorado elemento = buscarElementoIgnorado( p_em, p_propietario, p_usuario_id );
            if ( elemento == null) {
                throw new ExcepcionGeneral( -3, "Elemento no existe" + p_usuario_id  );
            }
            p_em.remove(elemento);
        }
        return 0;
    }


    public int wsSocial ( HttpServletRequest p_request, HttpServletResponse p_response ) {
        m_cadena = "";
        int     error       = 0;
        int     propietario  = -1;
        boolean amigo;
        EntityManager           em   = null;
log.debug("[SOCIAL INI] " );
        try {
            em = emf.createEntityManager(); // check 08.08.2012
log.debug("[SOCIAL BEGIN] " );
            em.getTransaction().begin();
log.debug("[SOCIAL END] " );
            String  operacion   = p_request.getParameter("op");
            String  tipo        = p_request.getParameter("t");

            HttpSession mi_sesion   = p_request.getSession(true);
            String      sesion_id   = mi_sesion.getId();
            if ( mi_sesion != null && sesion_id != null )
            {
                LoginAction la = new LoginAction();
                propietario = la.comprobarSesion ( sesion_id, em );

                if ( propietario < 0)
                    throw new ExcepcionGeneral( -9, "Sesión Incorrecta"  );
            } else {
                throw new ExcepcionGeneral( -9, "Sesión Incorrecta"  );
            }
log.debug("[SOCIAL 2 SESION CORRECTA] " );
            if ( operacion  == null )
                throw new ExcepcionGeneral( -5, "Operación Incorrecta"  );
            if ( tipo       == null )
                throw new ExcepcionGeneral( -6, "Tipo Incorrecto"  );
            if ( sesion_id  == null )
                throw new ExcepcionGeneral( -7, "Sesión Incorrecta"  );

log.debug("[SOCIAL 3OPERACION CORRECTA] " );
            if ( tipo.compareTo("f")==0 ) {
                amigo = true;
            } else if ( tipo.compareTo("b")==0  ){
                amigo = false;
            } else {
                throw new ExcepcionGeneral( -8, "Tipo Incorrecto"  );
            }

            if ( operacion.compareTo("l")==0 ) {
                log.debug("[LIST] "+ propietario + " amigo " + amigo );
                error = getLista ( em, amigo, propietario);
            } else if ( operacion.compareTo("a")==0  ){
                log.debug("[APPEND] "+ propietario + " amigo " + amigo );
                int  elemento_id = Integer.valueOf(p_request.getParameter("id"));
                error = appendLista ( em, amigo, propietario, elemento_id );
            } else if ( operacion.compareTo("d")==0  ){
                log.debug("[DELETE] "+ propietario + " amigo " + amigo);
                int  elemento_id = Integer.valueOf(p_request.getParameter("id"));
                error = removeLista ( em, amigo, propietario, elemento_id );
            } else {
                throw new ExcepcionGeneral( -4, "Operación Incorrecta"  );
            }
            em.getTransaction().commit();

        } catch (ExcepcionGeneral e) {
            log.error("[ERROR][wsSocial]: " , e);
            error=e.getCodigo();
            m_cadena="descripcion="+e.getDescripion();            
            if ( em.getTransaction().isActive())
                em.getTransaction().rollback();
        } catch (Exception e) {
            log.error("[ERROR][wsSocial]: " , e);
            error=-1;
            m_cadena=e.getMessage();
            if ( em.getTransaction().isActive())
                em.getTransaction().rollback();
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
log.debug("[SOCIAL FIN] " );
        return error;
    }
}







